#Region "Declarations"
Option Strict Off
Imports System.Runtime.InteropServices
Imports System.Security.Permissions
Imports System.Timers
Imports CommonNamespace
Imports System.Drawing.Bitmap
Imports System.Drawing.Imaging
Imports System.Windows.Forms
Imports System.IO
Imports ROIImageProcessingNamespace
Imports MetaView.AnnotatedImage
Imports MetaView
#End Region

Public Class ROIEditor
    Dim PassKey As String = ""
    Public Event PlotBackEvent(ByVal Values As ArrayList)
    Public Event changeslice As EventHandler

#Region "Declarations"
    Friend WithEvents oAnnotatedImage As AnnotatedImage
    Private ColorSegmentationParameters As New ColorSegmentation
    Public Enum ToolType
        None = 0
        SegmentByColor
    End Enum

    Private strToolTypeNames() As String = New String() {"None", "Segment"}

    Private iTool As ToolType

    Public Enum ColorSegmentationMode
        None = 0
        Point = 1
        Region = 2
        Image = 3
    End Enum

    Private Structure ColorSegmentation
        Dim ResampledBitmap, Mask, previousMask As Bitmap
        Dim UsedPreviousMask As Boolean
        Dim ResampleFactor, CloseOperations, SmoothingKernelSize As Integer
        Dim AnnotationContainerKey As String
        Dim RegionAddMode As RegionAddMode
        Dim SettingsForm As ColorSegmentationSettings
    End Structure

#End Region

#Region "Constructors"
    Dim RawData As Single(,)
    'RawData is used to export data to text files for particular ROI
    Public Sub New(ByVal oURI As Uri, ByVal oAnnotationURI As Uri)

        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        Me.oAnnotatedImage = Me.oAnnotatedsRGBImage.AnnotatedImage
        'AddHandler oAnnotatedImage.Draw, AddressOf drawregion

        'Make sure image form is maximized so we can measure the maximal clientsize
        Me.SuspendLayout()
        Me.WindowState = FormWindowState.Normal
        Dim rectScreen As Rectangle = Screen.PrimaryScreen.WorkingArea
        Dim objCurrentSize As Size = Me.Size
        Me.Width = rectScreen.Width
        Me.Height = rectScreen.Height - 20 'Dunno why, but we need to subtract 20
        Me.oAnnotatedsRGBImage.MaximimumSize = Me.ClientSize
        Me.ClientSize = objCurrentSize

        'Add the menus coming from the sRGBImage control
        Me.oAnnotatedsRGBImage.AddMenus()

        'Add own menus for tools
        Dim i As Integer
        For i = 1 To strToolTypeNames.GetUpperBound(0)
            Dim mnuItem As New MenuItem(strToolTypeNames(i), New System.EventHandler(AddressOf Me.ToolMenuItemEventHandler))
            mnuTools.MenuItems.Add(mnuItem)
        Next

        'Disable menus, they will be enabled when an image is loaded 
        Me.oAnnotatedsRGBImage.EnableMenus(Me.Menu, False)

        'If a valid filename is passed we show that image.
        If Not oURI Is Nothing Then Me.oAnnotatedsRGBImage.LoadImage(oURI)
        If Not oAnnotationURI Is Nothing Then Me.oAnnotatedsRGBImage.LoadAnnotations(oAnnotationURI)

        'Show annotations manager and add some menus
        Me.oAnnotatedImage.ShowAnnotationsManager(True)
        Me.oAnnotatedImage.ExtendAnnotationManagerMenu("Measure RGB", AnnotationManagerMenus.Annotation, New System.EventHandler(AddressOf Me.AnnotationsManagerMeasureMenuEventHandler))
        Me.oAnnotatedImage.ExtendAnnotationManagerMenu("Measure RGB", AnnotationManagerMenus.AnnotationContainer, New System.EventHandler(AddressOf Me.AnnotationsManagerMeasureMenuEventHandler))
        Me.oAnnotatedImage.ExtendAnnotationManagerMenu("Extract Points", AnnotationManagerMenus.Annotation, New EventHandler(AddressOf Me.SavePoints))
        Me.oAnnotatedImage.ExtendAnnotationManagerMenu("Extract Points", AnnotationManagerMenus.AnnotationContainer, New EventHandler(AddressOf Me.SavePoints))
        Me.ResumeLayout()
    End Sub

    Public ScaleConstant, InterceptConstant As Double
    Public Sub SavePoints(ByVal sender As Object, ByVal e As EventArgs)

        'get regions
        Dim oObject As Object = Me.oAnnotatedImage.GetAnnotationManagerSelectedObject()
        Dim oRegion As Region = Nothing
        If TypeOf oObject Is AnnotationContainer Then
            Dim oAnnContainer As AnnotationContainer = CType(oObject, AnnotationContainer)
            oRegion = oAnnContainer.GetRegion()

        ElseIf TypeOf oObject Is Annotation Then
            Dim oAnn As Annotation = CType(oObject, Annotation)
            oRegion = oAnn.GetRegion()
        End If

        If oRegion Is Nothing Then Exit Sub

        Dim counter As Integer = 1

        Dim temp As Integer = CInt(Mid(Me.PassKey, 2))

        Dim sfd As New SaveFileDialog
        sfd.Filter = "Excel/Matlab Tabbed Sheet(*.csv)|*.csv|All files (*.*)|*.*"

        If sfd.ShowDialog = Windows.Forms.DialogResult.OK Then
            Dim t As New FileInfo(sfd.FileName)
            Dim tex As StreamWriter = t.CreateText

            For i As Integer = 0 To Me.oAnnotatedImage.Bitmap.Width - 1
                For j As Integer = 0 To Me.oAnnotatedImage.Bitmap.Height - 1
                    If oRegion.IsVisible(i, j) = True Then
                        Select Case Mid(Me.PassKey, 1, 1)
                            Case "t"
                                tex.WriteLine(i & "," & j & "," & temp & "," & ((RawData(i, j)))) '/ Me.ScaleConstant) + Me.InterceptConstant))
                            Case "c"
                                tex.WriteLine(i & "," & temp & "," & j & "," & ((RawData(i, j)))) '/ Me.ScaleConstant) + Me.InterceptConstant))
                            Case "s"
                                tex.WriteLine(temp & "," & i & "," & j & "," & ((RawData(i, j)))) '/ Me.ScaleConstant) + Me.InterceptConstant))
                        End Select

                    End If
                Next
            Next
            tex.Write(tex.NewLine)
            tex.Close()
            MsgBox("Done!", MsgBoxStyle.OkOnly, "Done")
        End If
    End Sub

    Public Sub New(ByVal Bitmap As Bitmap, ByVal RawDataValues As Short(,), ByVal ScalingSlope As Double, ByVal ScalingIntercept As Double, Optional ByVal PassKey As String = "")
        Me.PassKey = PassKey
        Me.TopLevel = True

        ' This call is required by the Windows Form Designer. It initialized Passkey
        InitializeComponent()

        ReDim Me.RawData(RawDataValues.GetUpperBound(0), RawDataValues.GetUpperBound(1))
        For a As Integer = 0 To RawDataValues.GetUpperBound(0) - 1
            For b As Integer = 0 To RawDataValues.GetUpperBound(1) - 1
                RawData(a, b) = RawDataValues(a, b)
            Next
        Next
        '  Me.RawData = CType(RawDataValues, Single(,))
        ' Add any initialization after the InitializeComponent() call.
        'Me.oAnnotatedsRGBImage = New sRGBImageControlNamespace.AnnotatedsRGBImage(PassKey)
        Me.oAnnotatedsRGBImage.PassKey = PassKey
        'MsgBox(PassKey)
        Me.oAnnotatedImage = Me.oAnnotatedsRGBImage.AnnotatedImage
        ' AddHandler oAnnotatedImage.drawregion, AddressOf drawregion

        'Make sure image form is maximized so we can measure the maximal clientsize
        Me.SuspendLayout()
        Me.WindowState = FormWindowState.Normal
        Dim rectScreen As Rectangle = Screen.PrimaryScreen.WorkingArea
        Dim objCurrentSize As Size = Me.Size
        Me.Width = rectScreen.Width
        Me.Height = rectScreen.Height - 20 'Dunno why, but we need to subtract 20
        Me.oAnnotatedsRGBImage.MaximimumSize = Me.ClientSize
        '       Me.ClientSize = objCurrentSize
        '
        'Add the menus coming from the sRGBImage control
        Me.oAnnotatedsRGBImage.AddMenuswithBitmapLoad()

        'Add own menus for tools
        Dim i As Integer
        For i = 1 To strToolTypeNames.GetUpperBound(0)
            Dim mnuItem As New MenuItem(strToolTypeNames(i), New System.EventHandler(AddressOf Me.ToolMenuItemEventHandler))
            mnuTools.MenuItems.Add(mnuItem)
        Next

        'Disable menus, they will be enabled when an image is loaded 
        Me.oAnnotatedsRGBImage.EnableMenus(Me.Menu, False)

        'If a valid filename is passed we show that image.

        'save bitmap as temp file
        Dim fname As String = System.IO.Path.GetTempFileName
        Bitmap.Save(fname, ImageFormat.Bmp)
        '      Bitmap.Dispose()
        Dim ouri As New Uri(fname)
        If Not Bitmap Is Nothing Then Me.oAnnotatedsRGBImage.LoadImage(ouri)

        'Show annotations manager and add some menus
        Me.oAnnotatedImage.ShowAnnotationsManager(True)
        Me.oAnnotatedImage.ExtendAnnotationManagerMenu("Measure", AnnotationManagerMenus.Annotation, New System.EventHandler(AddressOf Me.AnnotationsManagerMeasureMenuEventHandler))
        Me.oAnnotatedImage.ExtendAnnotationManagerMenu("Measure", AnnotationManagerMenus.AnnotationContainer, New System.EventHandler(AddressOf Me.AnnotationsManagerMeasureMenuEventHandler))
        Me.oAnnotatedImage.ExtendAnnotationManagerMenu("Apply ROI as Map", AnnotationManagerMenus.Annotation, New System.EventHandler(AddressOf Me.AnnotationsManagerPlotBackMenuEventHandler))
        Me.oAnnotatedImage.ExtendAnnotationManagerMenu("Apply ROI as Map", AnnotationManagerMenus.AnnotationContainer, New System.EventHandler(AddressOf Me.AnnotationsManagerPlotBackMenuEventHandler))
        Me.oAnnotatedImage.ExtendAnnotationManagerMenu("Save Points", AnnotationManagerMenus.Annotation, New EventHandler(AddressOf Me.SavePoints))
        Me.oAnnotatedImage.ExtendAnnotationManagerMenu("Save Points", AnnotationManagerMenus.AnnotationContainer, New EventHandler(AddressOf Me.SavePoints))

        Me.ResumeLayout()
        Me.ScaleConstant = ScalingSlope
        Me.InterceptConstant = ScalingIntercept
    End Sub

    Public Sub New(ByVal Bitmap As Bitmap, ByVal RawDataValues As Single(,), ByVal ScalingSlope As Double, ByVal ScalingIntercept As Double, Optional ByVal PassKey As String = "")
        Me.TopLevel = True
        Me.PassKey = PassKey
        Me.ScaleConstant = ScalingSlope
        Me.InterceptConstant = ScalingIntercept
        ' This call is required by the Windows Form Designer. It initialized Passkey
        InitializeComponent()

        Me.RawData = RawDataValues
        ' Add any initialization after the InitializeComponent() call.
        Me.oAnnotatedImage = Me.oAnnotatedsRGBImage.AnnotatedImage
        ' AddHandler oAnnotatedImage.drawregion, AddressOf drawregion

        'Make sure image form is maximized so we can measure the maximal clientsize
        Me.SuspendLayout()
        Me.WindowState = FormWindowState.Normal
        Dim rectScreen As Rectangle = Screen.PrimaryScreen.WorkingArea
        Dim objCurrentSize As Size = Me.Size
        Me.Width = rectScreen.Width
        Me.Height = rectScreen.Height - 20 'Dunno why, but we need to subtract 20
        Me.oAnnotatedsRGBImage.MaximimumSize = Me.ClientSize
        Me.ClientSize = objCurrentSize

        'Add the menus coming from the sRGBImage control
        Me.oAnnotatedsRGBImage.AddMenuswithBitmapLoad()

        'Add own menus for tools
        Dim i As Integer
        For i = 1 To strToolTypeNames.GetUpperBound(0)
            Dim mnuItem As New MenuItem(strToolTypeNames(i), New System.EventHandler(AddressOf Me.ToolMenuItemEventHandler))
            mnuTools.MenuItems.Add(mnuItem)
        Next

        'Disable menus, they will be enabled when an image is loaded 
        Me.oAnnotatedsRGBImage.EnableMenus(Me.Menu, False)

        'If a valid filename is passed we show that image.

        'save bitmap as temp file
        Dim fname As String = System.IO.Path.GetTempFileName
        Bitmap.Save(fname, ImageFormat.Bmp)
        Bitmap.Dispose()
        Dim ouri As New Uri(fname)
        If Not Bitmap Is Nothing Then Me.oAnnotatedsRGBImage.LoadImage(ouri)

        'Show annotations manager and add some menus
        Me.oAnnotatedImage.ShowAnnotationsManager(True)
        Me.oAnnotatedImage.ExtendAnnotationManagerMenu("Measure", AnnotationManagerMenus.Annotation, New System.EventHandler(AddressOf Me.AnnotationsManagerMeasureMenuEventHandler))
        Me.oAnnotatedImage.ExtendAnnotationManagerMenu("Measure", AnnotationManagerMenus.AnnotationContainer, New System.EventHandler(AddressOf Me.AnnotationsManagerMeasureMenuEventHandler))
        Me.oAnnotatedImage.ExtendAnnotationManagerMenu("Plot in MetaView", AnnotationManagerMenus.Annotation, New System.EventHandler(AddressOf Me.AnnotationsManagerPlotBackMenuEventHandler))
        Me.oAnnotatedImage.ExtendAnnotationManagerMenu("Plot in MetaView", AnnotationManagerMenus.AnnotationContainer, New System.EventHandler(AddressOf Me.AnnotationsManagerPlotBackMenuEventHandler))
        Me.oAnnotatedImage.ExtendAnnotationManagerMenu("Save Points", AnnotationManagerMenus.Annotation, New EventHandler(AddressOf Me.SavePoints))
        Me.oAnnotatedImage.ExtendAnnotationManagerMenu("Save Points", AnnotationManagerMenus.AnnotationContainer, New EventHandler(AddressOf Me.SavePoints))

        Me.ResumeLayout()
        Me.oAnnotatedsRGBImage.AnnotatedImage.DisplayZoom = 1

    End Sub

    Public Sub New()

        ' This call is required by the Windows Form Designer.
        InitializeComponent()
        ' Add any initialization after the InitializeComponent() call.
        Me.oAnnotatedImage = Me.oAnnotatedsRGBImage.AnnotatedImage
        'AddHandler oAnnotatedImage., AddressOf drawregion

        'Make sure image form is maximized so we can measure the maximal clientsize
        Me.SuspendLayout()
        Me.WindowState = FormWindowState.Normal
        Dim rectScreen As Rectangle = Screen.PrimaryScreen.WorkingArea
        Dim objCurrentSize As Size = Me.Size
        Me.Width = rectScreen.Width
        Me.Height = rectScreen.Height - 20 'Dunno why, but we need to subtract 20
        Me.oAnnotatedsRGBImage.MaximimumSize = Me.ClientSize
        Me.ClientSize = objCurrentSize

        'Add the menus coming from the sRGBImage control
        Me.oAnnotatedsRGBImage.AddMenuswithBitmapLoad()

        'Add own menus for tools
        Dim i As Integer
        For i = 1 To strToolTypeNames.GetUpperBound(0)
            Dim mnuItem As New MenuItem(strToolTypeNames(i), New System.EventHandler(AddressOf Me.ToolMenuItemEventHandler))
            mnuTools.MenuItems.Add(mnuItem)
        Next

        'Disable menus, they will be enabled when an image is loaded 
        Me.oAnnotatedsRGBImage.EnableMenus(Me.Menu, False)

        'Show annotations manager and add some menus
        'Me.oAnnotatedImage.ShowAnnotationsManager(Me)
        Me.oAnnotatedImage.ExtendAnnotationManagerMenu("Measure", AnnotationManagerMenus.Annotation, New System.EventHandler(AddressOf Me.AnnotationsManagerMeasureMenuEventHandler))
        Me.oAnnotatedImage.ExtendAnnotationManagerMenu("Measure", AnnotationManagerMenus.AnnotationContainer, New System.EventHandler(AddressOf Me.AnnotationsManagerMeasureMenuEventHandler))
        Me.ResumeLayout()
        Me.oAnnotatedsRGBImage.AnnotatedImage.DisplayZoom = 1

    End Sub

    Public Sub SwitchImage(ByVal Bitmap As Bitmap, ByVal RawDataValues As Single(,), ByVal ScalingSlope As Double, ByVal ScalingIntercept As Double, Optional ByVal PassKey As String = "")
        Me.PassKey = PassKey
        Me.ScaleConstant = ScalingSlope
        Me.InterceptConstant = ScalingIntercept
        Dim oAnnotationURI As Uri = Me.oAnnotatedsRGBImage.AnnotatedImage.AnnotationsURI

        Me.RawData = RawDataValues
        ' Add any initialization after the InitializeComponent() call.
        Me.oAnnotatedImage = Me.oAnnotatedsRGBImage.AnnotatedImage
        ' AddHandler oAnnotatedImage.drawregion, AddressOf drawregion

        'save bitmap as temp file
        Dim fname As String = System.IO.Path.GetTempFileName
        Bitmap.Save(fname, ImageFormat.Bmp)
        Bitmap.Dispose()
        Dim ouri As New Uri(fname)
        Dim oldzoom As Integer = Me.oAnnotatedsRGBImage.AnnotatedImage.DisplayZoom
        If Not Bitmap Is Nothing Then Me.oAnnotatedsRGBImage.LoadImage(ouri)
        Me.oAnnotatedsRGBImage.AnnotatedImage.DisplayZoom = oldzoom
        Me.oAnnotatedsRGBImage.oAnnotatedImage.PassKey = PassKey
        Me.oAnnotatedsRGBImage.PassKey = PassKey
        If Not oAnnotationURI Is Nothing Then Me.oAnnotatedsRGBImage.LoadAnnotations(oAnnotationURI)
    End Sub
    Public Sub SwitchImage(ByVal Bitmap As Bitmap, ByVal RawDataValues As Int16(,), ByVal ScalingSlope As Double, ByVal ScalingIntercept As Double, Optional ByVal PassKey As String = "")
        Me.PassKey = PassKey
        Me.ScaleConstant = ScalingSlope
        Me.InterceptConstant = ScalingIntercept
        Dim oAnnotationURI As Uri = Me.oAnnotatedsRGBImage.AnnotatedImage.AnnotationsURI
        ReDim Me.RawData(RawDataValues.GetUpperBound(0), RawDataValues.GetUpperBound(1))
        For a As Integer = 0 To RawDataValues.GetUpperBound(0) - 1
            For b As Integer = 0 To RawDataValues.GetUpperBound(1) - 1
                RawData(a, b) = RawDataValues(a, b)
            Next
        Next
        ' Add any initialization after the InitializeComponent() call.
        Me.oAnnotatedImage = Me.oAnnotatedsRGBImage.AnnotatedImage
        ' AddHandler oAnnotatedImage.drawregion, AddressOf drawregion

        'save bitmap as temp file
        Dim fname As String = System.IO.Path.GetTempFileName
        Bitmap.Save(fname, ImageFormat.Bmp)
        Bitmap.Dispose()
        Dim ouri As New Uri(fname)
        Dim oldzoom As Integer = Me.oAnnotatedsRGBImage.AnnotatedImage.DisplayZoom
        If Not Bitmap Is Nothing Then Me.oAnnotatedsRGBImage.LoadImage(ouri)
        Me.oAnnotatedsRGBImage.AnnotatedImage.DisplayZoom = oldzoom
        Me.oAnnotatedsRGBImage.PassKey = PassKey
        Me.oAnnotatedsRGBImage.oAnnotatedImage.PassKey = PassKey
        If Not oAnnotationURI Is Nothing Then Me.oAnnotatedsRGBImage.LoadAnnotations(oAnnotationURI)

    End Sub

#End Region

#Region "Properties"
    Private Property Tool() As ToolType
        Get
            Return Me.iTool
        End Get
        Set(ByVal Value As ToolType)
            If Me.iTool = ToolType.None Or Value = ToolType.None Then
                'We can only engage a new tool if others have finished, or if we canceled a tool by setting it to none

                ' Set tool menu item and private var
                With mnuTools
                    If Me.iTool > 0 Then .MenuItems(Me.iTool - 1).Checked = False
                    If Value > 0 Then .MenuItems(Value - 1).Checked = True
                End With
                Me.iTool = Value

                'This MUST be set before going into the tools themselves, as these may exit by setting the tool to None 
                'if something goes wrong
                If Value = ToolType.None Then
                    Me.oAnnotatedsRGBImage.EnableMenus(mnuMain, True, True)
                Else
                    Me.oAnnotatedsRGBImage.EnableMenus(mnuMain, False, True)
                End If

                Select Case Value
                    Case ToolType.SegmentByColor
                        Me.SelectToolSegmentByColor()
                    Case ToolType.None
                End Select
            Else
                MessageBox.Show("Cannot start new tool before exiting current one!", "sRGB Tool", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End If
        End Set
    End Property

#End Region

#Region "Form event handlers"
    Dim ROIPolygonPoints() As PointF

    Protected Sub AnnotationsManagerMeasureMenuEventHandler(ByVal sender As System.Object, ByVal e As System.EventArgs)
        'Extension for one of the annotations manager context menus
        Dim oObject As Object = Me.oAnnotatedImage.GetAnnotationManagerSelectedObject()

        If TypeOf oObject Is AnnotationContainer Then
            Dim oAnnContainer As AnnotationContainer = CType(oObject, AnnotationContainer)
            Dim oRegion As Region = oAnnContainer.GetRegion()
            Dim sRGB(2), sLAb(2), sArea As Single
            ImageProcessing.MeasureRegion(Me.oAnnotatedImage.Bitmap, oRegion, sRGB, sLAb, sArea)

            Dim strText As String = "ROI container " & oAnnContainer.Key & vbNewLine
            strText = strText & "Area: " & sArea.ToString() & " cm^2" & vbNewLine
            strText = strText & "Average sRGB: " & ColorUtil.ToString(sRGB) & vbNewLine
            strText = strText & "Average sLab: " & ColorUtil.ToString(sLAb) & vbNewLine
            MessageBox.Show(strText, "Measurement", MessageBoxButtons.OK, MessageBoxIcon.Information)
        ElseIf TypeOf oObject Is Annotation Then
            Dim oAnn As Annotation = CType(oObject, Annotation)
            Dim oRegion As Region = oAnn.GetRegion()
            Dim sRGB(2), sLAb(2), sArea, sPathLength As Single
            ImageProcessing.MeasureRegion(Me.oAnnotatedImage.Bitmap, oRegion, sRGB, sLAb, sArea)
            sPathLength = CSng(oAnn.GetLength() * 2.54 / Me.oAnnotatedImage.Bitmap.HorizontalResolution)
            Dim strText As String = "ROI " & oAnn.Key & vbNewLine
            strText = strText & "Area: " & sArea.ToString() & " cm^2" & vbNewLine
            strText = strText & "Path length: " & sPathLength.ToString() & " cm" & vbNewLine
            strText = strText & "Average sRGB: " & ColorUtil.ToString(sRGB) & vbNewLine
            strText = strText & "Average sLab: " & ColorUtil.ToString(sLAb) & vbNewLine
            MessageBox.Show(strText, "Measurement", MessageBoxButtons.OK, MessageBoxIcon.Information)
        End If
    End Sub
    Protected Sub AnnotationsManagerPlotBackMenuEventHandler(ByVal sender As System.Object, ByVal e As System.EventArgs)
        'Extension for one of the annotations manager context menus
        'get regions
        Dim oObject As Object = Me.oAnnotatedImage.GetAnnotationManagerSelectedObject()
        Dim oRegion As Region = Nothing
        If TypeOf oObject Is AnnotationContainer Then
            Dim oAnnContainer As AnnotationContainer = CType(oObject, AnnotationContainer)
            oRegion = oAnnContainer.GetRegion()

        ElseIf TypeOf oObject Is Annotation Then
            Dim oAnn As Annotation = CType(oObject, Annotation)
            oRegion = oAnn.GetRegion()
        End If

        If oRegion Is Nothing Then Exit Sub

        Dim counter As Integer = 1

        Dim temp As Integer = CInt(Mid(Me.PassKey, 2))

        Dim pointsArrayList As New ArrayList()

        For i As Integer = 0 To Me.oAnnotatedImage.Bitmap.Width - 1
            For j As Integer = 0 To Me.oAnnotatedImage.Bitmap.Height - 1
                If oRegion.IsVisible(i, j) = True Then
                    pointsArrayList.Add(New Integer() {i, j})
                End If
            Next
        Next
        RaiseEvent PlotBackEvent(pointsArrayList)
    End Sub
#End Region

#Region "Annotated sRGB Image event handlers"

    Protected Sub ToolMenuItemEventHandler(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Me.Tool = sender.index + 1
    End Sub

    'Private Sub AnnotatedsRGBImageResize(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles oAnnotatedsRGBImage.Resize
    '    Resize parent form to user control. Causes refresh ....
    '    Debug.WriteLine("Received resize event from AnnotatedsRGBImage, resizing client area", "AnnotatedsRGBImageResize")
    '    Me.ClientSize = Me.oAnnotatedsRGBImage.Size
    '    Me.Refresh()
    'End Sub

    Private Sub AnnotatedsRGBImageAnnotationCreationMouseMove(ByVal e As System.Windows.Forms.MouseEventArgs, ByVal objAnn As AnnotatedImage.Annotation) Handles oAnnotatedsRGBImage.AnnotationCreationMouseMove
        Select Case Me.Tool
            Case ToolType.None
        End Select
    End Sub

    Private Sub AnnotatedsRGBImageAnnotationCreationPointAdded(ByVal objAnnotation As AnnotatedImage.Annotation) Handles oAnnotatedsRGBImage.AnnotationCreationPointAdded
        Debug.WriteLine("Point added", "Toolbox handling AnnotatedsRGBImage event")
        Select Case Me.Tool
            Case ToolType.SegmentByColor
                SegmentByColorAddPoint(objAnnotation)
        End Select
    End Sub

    Private Sub AnnotatedsRGBImageAnnotationCreationDone(ByVal objAnn As AnnotatedImage.Annotation) Handles oAnnotatedsRGBImage.AnnotationCreationDone
        Select Case Me.Tool
            Case ToolType.SegmentByColor
                DoneToolSegmentByColor(False)
        End Select

        'Go back to none tool
        Me.Tool = ToolType.None
    End Sub

    Private Sub AnnotatedsRGBImageAnnotationCreationCanceled(ByVal objAnn As AnnotatedImage.Annotation) Handles oAnnotatedsRGBImage.AnnotationCreationCanceled
        'Go back to none tool after eventual cleanup
        Select Case Me.Tool
            Case ToolType.SegmentByColor
                DoneToolSegmentByColor(True)
        End Select
        Me.Tool = ToolType.None
    End Sub

    Private Sub AnnotatedsRGBImageAnnotationCreationPointRemoved(ByVal objAnnotation As AnnotatedImage.Annotation) Handles oAnnotatedsRGBImage.AnnotationCreationPointRemoved
        Select Case Me.Tool
            Case ToolType.SegmentByColor
                'Return to previous mask
                'As the mask is actually a reference to the one inside anotatedImage, this 
                'will redraw it too
                If Not ColorSegmentationParameters.previousMask Is Nothing Then

                    If ColorSegmentationParameters.UsedPreviousMask Then
                        MessageBox.Show("There is only one undo level!", "Segment by Color", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
                    Else
                        ColorSegmentationParameters.previousMask.Save("C:\temp\PreviousMask.png")
                        ImageProcessing.Copy(ColorSegmentationParameters.previousMask, ColorSegmentationParameters.Mask)
                        Me.oAnnotatedsRGBImage.Refresh()
                        ColorSegmentationParameters.UsedPreviousMask = True
                    End If
                End If
        End Select
    End Sub
#End Region

#Region "Selection of tools"
    Private Sub SelectToolSegmentByColor()
        If Image.GetPixelFormatSize(Me.oAnnotatedImage.Bitmap.PixelFormat) > 8 Then

            Dim oColorSgementationPreprocessing As New ColorSegmentationPreprocessing
            If oColorSgementationPreprocessing.ShowDialog() = Windows.Forms.DialogResult.OK Then
                ColorSegmentationParameters.CloseOperations = 0
                ColorSegmentationParameters.ResampleFactor = CInt(oColorSgementationPreprocessing.nudUnderSampling.Value)
                ColorSegmentationParameters.SmoothingKernelSize = CInt(oColorSgementationPreprocessing.nudSmoothing.Value)

                'Find next segment container
                Dim iConNr As Integer = 0
                Dim oAnnContainer As AnnotationContainer
                Dim strAnnContainerKey As String
                Do
                    iConNr += 1
                    strAnnContainerKey = "Segment" & iConNr
                    oAnnContainer = oAnnotatedImage.AnnotationContainers(strAnnContainerKey)
                Loop Until oAnnContainer Is Nothing
                oAnnContainer = New AnnotationContainer(Color.FromArgb(64, 0, 255, 0))
                oAnnotatedImage.AnnotationContainers.Add(oAnnContainer, strAnnContainerKey)

                ColorSegmentationParameters.AnnotationContainerKey = strAnnContainerKey
                Dim objPtAnn As New Annotation(False)
                objPtAnn.PointSize = 3
                objPtAnn.LineWidth = 0
                oAnnContainer.Annotations.Add(objPtAnn, "Seeds")

                'Create a subsampled temporary smoothed image for faster processing
                ColorSegmentationParameters.ResampledBitmap = ImageProcessing.Resize(Me.oAnnotatedImage.Bitmap, CSng(1 / ColorSegmentationParameters.ResampleFactor))
                ImageProcessing.Convolve(ColorSegmentationParameters.ResampledBitmap, ImageProcessing.ConvolutionKernelType.Blur, ColorSegmentationParameters.SmoothingKernelSize)
                ColorSegmentationParameters.Mask = New Bitmap(ColorSegmentationParameters.ResampledBitmap.Width, _
                                                              ColorSegmentationParameters.ResampledBitmap.Height, System.Drawing.Imaging.PixelFormat.Format1bppIndexed)

                Dim oPalette As ColorPalette = ColorSegmentationParameters.Mask.Palette
                oPalette.Entries(0) = Color.Transparent
                oPalette.Entries(1) = oAnnContainer.Color
                ColorSegmentationParameters.Mask.Palette = oPalette
                Me.oAnnotatedImage.Masks.Add(ColorSegmentationParameters.Mask, "ColorMask")
                ColorSegmentationParameters.previousMask = New Bitmap(ColorSegmentationParameters.ResampledBitmap.Width, _
                                                              ColorSegmentationParameters.ResampledBitmap.Height, System.Drawing.Imaging.PixelFormat.Format1bppIndexed)
                ColorSegmentationParameters.SettingsForm = New ColorSegmentationSettings
                ColorSegmentationParameters.SettingsForm.Owner = Me
                ColorSegmentationParameters.SettingsForm.Show()

                'Start interactive creation of points
                oAnnotatedImage.CreateAnnotation(objPtAnn)
            End If
        End If


    End Sub

#End Region

#Region "Inside Tools"
    Private Sub SegmentByColorAddPoint(ByVal objAnnotation As Annotation)
        'Get seed ColorUtil. We need to scale it to the temporary subsampled image
        Dim oAnnContainer As AnnotationContainer = objAnnotation.AnnotationContainer
        Dim oSeedPt As Point = objAnnotation.Points(objAnnotation.Points.Count - 1)
        Dim oImageRect As New Rectangle(0, 0, Me.oAnnotatedImage.Bitmap.Width, Me.oAnnotatedImage.Bitmap.Height)
        oSeedPt.X = CInt(Math.Round(oSeedPt.X / ColorSegmentationParameters.ResampleFactor))
        oSeedPt.Y = CInt(Math.Round(oSeedPt.Y / ColorSegmentationParameters.ResampleFactor))

        'Get region and scale to subsample factor. We need to clone it because 
        'the image processing routines may need to lock them!
        Dim oMask As Bitmap = ColorSegmentationParameters.Mask
        ImageProcessing.Copy(oMask, ColorSegmentationParameters.previousMask)
        ColorSegmentationParameters.UsedPreviousMask = False


        'Get settings
        Dim iMode As ColorSegmentationMode, bUseOnlyChroma As Boolean, sDE As Single
        With ColorSegmentationParameters.SettingsForm
            sDE = .dE
            bUseOnlyChroma = .ChromaticInfoOnly
            iMode = .Mode
        End With

        Select Case iMode
            Case ColorSegmentationMode.Image
                Dim oColor As Color = ColorSegmentationParameters.ResampledBitmap.GetPixel(oSeedPt.X, oSeedPt.Y)
                Dim oColorutil As New ColorUtil, sRGB(2) As Single, sLab(2) As Single
                ColorUtil.ColorToRGB(oColor, sRGB)
                oColorutil.sRGBToCIELab(sRGB, sLab)
                ImageProcessing.Find(ColorSegmentationParameters.ResampledBitmap, oMask, sLab, sDE)
                Me.oAnnotatedsRGBImage.Refresh()
            Case ColorSegmentationMode.Point
            Case ColorSegmentationMode.Region
                Do While ImageProcessing.Grow(ColorSegmentationParameters.ResampledBitmap, oMask, oSeedPt, sDE, bUseOnlyChroma, 10) = False
                    If ColorSegmentationParameters.CloseOperations > 0 Then ImageProcessing.Morphology(oMask, ImageProcessing.BitmapMaskMorphologyOperation.Close, ColorSegmentationParameters.CloseOperations)
                    Me.oAnnotatedsRGBImage.Refresh()
                Loop
        End Select

        'Me.oAnnotatedImage.Updating = True
        'Me.oAnnotatedImage.Updating = False
    End Sub

    Private Sub MaskToAnnotations(ByVal oAnnContainer As AnnotationContainer, ByVal oMask As Bitmap)
        Dim oMaskBorderPts As ArrayList = ImageProcessing.GetBorderPoints(oMask)

        Dim i, j As Integer
        For i = 1 To oAnnContainer.Annotations.Count - 1
            oAnnContainer.Annotations.Remove(1)
        Next
        For i = 0 To oMaskBorderPts.Count - 1
            Dim oPtAnn As New Annotation
            Dim oPts() As Point = CType(oMaskBorderPts.Item(i), Point())
            For j = 0 To oPts.Length - 1
                oPts(j).X *= ColorSegmentationParameters.ResampleFactor
                oPts(j).Y *= ColorSegmentationParameters.ResampleFactor
            Next
            oPtAnn.PointSize = 0
            oPtAnn.Closed = True
            'oPtAnn.RegionAddMode = ColorSegmentationParameters.RegionAddMod
            oPtAnn.Points.AddArray(oPts)

            oAnnContainer.Annotations.Add(oPtAnn, i.ToString)
        Next
    End Sub
#End Region

#Region "Done with tools"
    Private Sub DoneToolSegmentByColor(ByVal bCancel As Boolean)
        Dim oContainer As AnnotationContainer = Me.oAnnotatedImage.AnnotationContainers(ColorSegmentationParameters.AnnotationContainerKey)
        Me.oAnnotatedImage.Updating = True

        If bCancel Then
            oContainer.Annotations.Clear()
        Else
            oContainer.Annotations.Remove("Seeds")
            ImageProcessing.Morphology(ColorSegmentationParameters.Mask, ImageProcessing.BitmapMaskMorphologyOperation.Close)
            If ColorSegmentationParameters.SettingsForm.Invert Then ImageProcessing.Invert(ColorSegmentationParameters.Mask)
            MaskToAnnotations(oContainer, ColorSegmentationParameters.Mask)
        End If

        'Remove masks
        Me.oAnnotatedImage.Masks.Clear()
        ColorSegmentationParameters.Mask = Nothing
        ColorSegmentationParameters.previousMask = Nothing

        ColorSegmentationParameters.SettingsForm.Close()
        Me.oAnnotatedImage.Updating = False
    End Sub
#End Region

#Region " Closing"
    Private Sub sRGBToolboxForm_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
        If Me.oAnnotatedsRGBImage.ModifiedImage Or Me.oAnnotatedsRGBImage.ModifiedAnnotations Then
            If SkippableMessage.Show(Me, "Closing", "Closing", "You have modified the image or its ROIs, do you wish to save them?", True, True, False) = Windows.Forms.DialogResult.Yes Then
                Me.oAnnotatedsRGBImage.SaveAnnotationsAs()
            End If
        End If
    End Sub
    Private Sub MenuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItem1.Click
        RaiseEvent changeslice("p" & PassKey, EventArgs.Empty)
    End Sub
    Private Sub MenuItem2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItem2.Click
        RaiseEvent changeslice("n" & PassKey, EventArgs.Empty)
    End Sub
    Private Sub MenuItem3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MenuItem3.Click
        Me.Close()
    End Sub
#End Region

End Class